package ru.mirent.entity.executors;

import lombok.extern.slf4j.Slf4j;
import ru.mirent.entity.listeners.event.MultipleNotificationListener;
import ru.mirent.entity.notifications.FixtureNotification;

/**
 * Реализация наблюдателя за множеством типов уведомлений с запуском асинхронного задания в отдельном от основного потоке.
 * Запускаемое задание выполняется в отдельном потоке и не занимает основной поток.
 */
@Slf4j
public class AsyncMultipleJob extends MultipleNotificationListener {

    @SafeVarargs
    public AsyncMultipleJob(Class<? extends FixtureNotification>... notification) {
        super(notification);
    }

    @Override
    public void update(Class<? extends FixtureNotification> notification) {
        // TODO Добавить остановку задания
        if (getNotificationsList().contains(notification)) {
            log.info(" [" + notification.getSimpleName() + "] Начал работу: " + notification.getSimpleName());

            new ExampleThread(notification).start();

            log.info(" [" + notification.getSimpleName() + "] Завершил работу: " + notification.getSimpleName());
        }
    }

    /**
     * Внутренне задание, запускаемое в отдельном потоке
     */
    static class ExampleThread extends Thread {
        private final Class<? extends FixtureNotification> notification;

        public ExampleThread(Class<? extends FixtureNotification> notification) {
            this.notification = notification;
        }

        @Override
        public void run() {
            log.info("[" + notification.getSimpleName() + "] Запущен метод потока: " + this.getId());
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(100);
                    log.info("[" + notification.getSimpleName() + "] Выполнено действие потока: " + this.getId());
                } catch (InterruptedException ignored) {}
            }
        }
    }
}
